package com.atguigu.feature.reference;

import com.atguigu.feature.entity.Employee;
import com.atguigu.feature.entity.Student;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class DemoMethodReference {

    @Test
    public void test01() {
        List<String> list = Arrays.asList("a", "b", "c");

        list.stream().forEach((str) -> {
            System.out.println(str);
        });

        System.out.println();

        list.stream().forEach(str -> System.out.println(str));

        System.out.println();

        // 方法引用
        list.stream().forEach(System.out::println);
    }

    @Test
    public void test02() {
        List<String> list = Arrays.asList("a", "b", "c");

        List<Student> studentList = list.stream().map(str -> {
            return new Student(str);
        }).collect(Collectors.toList());

        studentList = list.stream().map(str -> new Student(str)).collect(Collectors.toList());

        // 构造器引用
        studentList = list.stream().map(Student::new).collect(Collectors.toList());

        for (Student student : studentList) {
            System.out.println("student = " + student);
        }
    }

    @Test
    public void test03UseRef() {
        // 场景：实例对象::方法名
        List<String> list = Arrays.asList("tom", "jerry", "harry");

        // 未改造的 Lambda 表达式
        list.forEach(value -> {System.out.println(value);});

        // 使用方法引用改造后的 Lambda 表达式
        list.forEach(System.out::println);
    }

    @Test
    public void test04UseRef() {
        // 1、创建 Employee 对象
        Employee employee = new Employee();

        // 2、创建 Stream 对象
        Stream.generate(()->{ return Math.random();})
                .peek(number -> {
                    employee.setEmpSalary(number);
                }).limit(1).count();

        // 改成方法引用的写法
        Stream.generate(()->{ return Math.random();})
                .peek(employee::setEmpSalary).limit(1).count();

        System.out.println("employee = " + employee);
    }

    @Test
    public void test05UseRef() {
        Employee employee = new Employee();
        employee.setEmpSalary(1000.00d);

//        Stream.generate(()->{return employee.getEmpSalary();}).limit(1).forEach(salary -> {
//            System.out.println("salary = " + salary);
//        });

        // 创建一个 Stream 对象测试没有参数时使用方法引用
        Stream.generate(employee::getEmpSalary).limit(1).forEach(salary -> {
            System.out.println("salary = " + salary);
        });
    }

    @Test
    public void test06UseRef() {

        // 1、创建对象
        Employee employee = new Employee(5, "harry~", 5511d);

        // 2、使用 Lambda 表达式创建 BiConsumer 类型的对象
//        BiConsumer<String, Integer> biConsumer = (String empName, Integer empId)->{
//            employee.printEmpNameAndId(empName, empId);
//        };

        // 使用方法引用修改 Lambda 体
        BiConsumer<String, Integer> biConsumer = employee::printEmpNameAndId;

        // 3、调用 BiConsumer 对象的方法
        biConsumer.accept(employee.getEmpName(), employee.getEmpId());
    }

    @Test
    public void test07UseRef() {
        // 类名::静态方法
        Double goodValue = null;

//        Double optionalGetValue = Optional.ofNullable(goodValue).orElseGet(() -> {
//            return Math.random();
//        });

        // () -> {return Math.random();}
        Double optionalGetValue = Optional.ofNullable(goodValue).orElseGet(Math::random);

        System.out.println("optionalGetValue = " + optionalGetValue);
    }

    @Test
    public void test08UseRef() {
        // 类名::非静态方法
        // 类名： Lambda 表达式唯一参数的类型
        // 非静态方法：Lambda 体中唯一参数调用的方法
        Arrays.asList("a", "bb", "ccc")
                .stream()
                // .map((String value)->{return value.length();})
                //.map(value -> value.length())
                .map(String::length)
                .forEach((len)->{
                    System.out.println("len = " + len);
                });
    }

    @Test
    public void test09UseRef() {
        // 类名::非静态方法
        Integer maxValue = Arrays.asList(23, 45, 18, 22, 17)
                .stream()
                // .max((Integer value01, Integer value02) -> {return value01.compareTo(value02);})
                // .max((value01, value02) -> value01.compareTo(value02))
                .max(Integer::compareTo)
                .get();

        System.out.println("maxValue = " + maxValue);
    }

    @Test
    public void test10UseRef() {
        // 类名::new
        Arrays.asList("tom~@", "jerry~@", "harry~@")
                .stream()
                // .map((String str) -> { return new Student(str);} )
                // .map(str -> new Student(str))
                .map(Student::new)
                .forEach(System.out::println);
    }

    @Test
    public void test11UseRef() {
        List<Integer> lenList = Arrays.asList(2, 3, 4);

        // .map((len) -> {return new String[len]{};})
        // .map(len -> new String[len]{})
        lenList.stream().map(String[]::new).forEach(arr -> {
            System.out.println(arr.length);
        });
    }
}
